/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package scheduleManager;

import app.Global;
import app.MyModel;
import entities.Employee;
import entities.EmployeeSchedule;
import entities.TimeSlot;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author yoshi
 */
public class ScheduleManagerModel implements MyModel {

    private ArrayList<EmployeeSchedule> schedules = new ArrayList<EmployeeSchedule>();
    private ArrayList<TimeSlot> timeSlots = new ArrayList<TimeSlot>();
    private ArrayList<Employee> employees = new ArrayList<Employee>();
    private long departmentId;

    public ScheduleManagerModel(long departmentId) {
        this.departmentId = departmentId;
    }

    public ArrayList<EmployeeSchedule> getSchedules() {
        return schedules;
    }

    public ArrayList<TimeSlot> getTimeSlots() {
        return timeSlots;
    }

    public void setDepartmentId(long departmentId) {
        this.departmentId = departmentId;
    }

    public void initDefault() {
        schedules.clear();
        Connection connection = Global.getConnection();
        PreparedStatement st = null;
        ResultSet rs = null;

        try {
            String query = Global.getScheduleQuery()
                    + " WHERE e.department_id = ? AND e.active = 1 AND s.status = 1"
                    + " ORDER BY s.date ASC, s.time_slot_id ASC";

            st = connection.prepareStatement(query);
            st.setLong(1, departmentId);
            rs = st.executeQuery();

            int count = 0;
            while (rs.next()) {
                schedules.add(new EmployeeSchedule(rs));
            }

        } catch (SQLException ex) {
            Logger.getLogger(AbstractScheduleManagerView.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                rs.close();
                st.close();
                connection.close();
            } catch (SQLException ex) {
                Logger.getLogger(AbstractScheduleManagerView.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void initAssignHead(Calendar calendar) {
        final ScheduleManagerModel self = this;
        schedules.clear();
        timeSlots.clear();
        employees.clear();
        final Connection connection = Global.getConnection();
        PreparedStatement st = null;
        ResultSet rs = null;

        Calendar cal = (Calendar) calendar.clone();
        cal.add(Calendar.DAY_OF_WEEK, -cal.get(Calendar.DAY_OF_WEEK) + 1);
        Date startDate = new Date(cal.getTime().getTime());
        cal.add(Calendar.DAY_OF_WEEK, 7);
        Date endDate = new Date(cal.getTime().getTime());

        try {
            String query = Global.getScheduleQuery()
                    + " WHERE e.department_id = ? AND e.active = 1 AND s.status = 1"
                    + " AND r.head = 1 AND s.date > ? AND s.date <= ?"
                    + " ORDER BY s.date ASC, s.time_slot_id ASC";

            st = connection.prepareStatement(query);
            st.setLong(1, departmentId);
            st.setDate(2, startDate);
            st.setDate(3, endDate);
            rs = st.executeQuery();

            while (rs.next()) {
                schedules.add(new EmployeeSchedule(rs));
            }

            rs = st.executeQuery(Global.getTimeSlotQuery());
            while (rs.next()) {
                timeSlots.add(new TimeSlot(rs));
            }

            // run background
            new Thread() {

                @Override
                public void run() {
                    ResultSet rs = null;
                    PreparedStatement st = null;
                    try {
                        st = connection.prepareStatement(Global.getEmployeeQuery()
                                + " WHERE e.active = 1 AND r.head = 1 AND e.department_id = ?");
                        st.setLong(1, departmentId);
                        rs = st.executeQuery();

                        while (rs.next()) {
                            employees.add(new Employee(rs));
                        }
                    } catch (SQLException ex) {
                        Logger.getLogger(ScheduleManagerModel.class.getName()).log(Level.SEVERE, null, ex);
                    } finally {
                        try {
                            rs.close();
                            st.close();
                            connection.close();
                        } catch (SQLException ex) {
                            Logger.getLogger(ScheduleManagerModel.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }
            }.start();
        } catch (SQLException ex) {
            Logger.getLogger(AbstractScheduleManagerView.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                rs.close();
                st.close();
            } catch (SQLException ex) {
                Logger.getLogger(AbstractScheduleManagerView.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public Employee[] getEmployees() {
        return employees.toArray(new Employee[employees.size()]);
    }

    @Override
    public void clear() {
        schedules.clear();
        timeSlots.clear();
        employees.clear();
    }

    void initAssignEmployee(Calendar calendar) {
        final ScheduleManagerModel self = this;
        schedules.clear();
        timeSlots.clear();
        employees.clear();
        final Connection connection = Global.getConnection();
        PreparedStatement st = null;
        ResultSet rs = null;

        Calendar cal = (Calendar) calendar.clone();
        cal.add(Calendar.DAY_OF_WEEK, -cal.get(Calendar.DAY_OF_WEEK) + 1);
        Date startDate = new Date(cal.getTime().getTime());
        cal.add(Calendar.DAY_OF_WEEK, 7);
        Date endDate = new Date(cal.getTime().getTime());

        try {
            String query = Global.getScheduleQuery()
                    + " WHERE e.department_id = ? AND e.active = 1 AND s.status = 1"
                    + " AND r.head = 0 AND s.date > ? AND s.date < ?"
                    + " ORDER BY s.date ASC, s.time_slot_id ASC";

            st = connection.prepareStatement(query);
            st.setLong(1, departmentId);
            st.setDate(2, startDate);
            st.setDate(3, endDate);
            rs = st.executeQuery();

            while (rs.next()) {
                schedules.add(new EmployeeSchedule(rs));
            }

            rs = st.executeQuery(Global.getTimeSlotQuery());
            while (rs.next()) {
                timeSlots.add(new TimeSlot(rs));
            }

            // run background
            new Thread() {

                @Override
                public void run() {
                    ResultSet rs = null;
                    PreparedStatement st = null;
                    try {
                        st = connection.prepareStatement(Global.getEmployeeQuery()
                                + " WHERE e.active = 1 AND r.head = 0 AND e.department_id = ?");
                        st.setLong(1, departmentId);
                        rs = st.executeQuery();

                        while (rs.next()) {
                            employees.add(new Employee(rs));
                        }
                    } catch (SQLException ex) {
                        Logger.getLogger(ScheduleManagerModel.class.getName()).log(Level.SEVERE, null, ex);
                    } finally {
                        try {
                            rs.close();
                            st.close();
                            connection.close();
                        } catch (SQLException ex) {
                            Logger.getLogger(ScheduleManagerModel.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }
            }.start();
        } catch (SQLException ex) {
            Logger.getLogger(AbstractScheduleManagerView.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                rs.close();
                st.close();
            } catch (SQLException ex) {
                Logger.getLogger(AbstractScheduleManagerView.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}
